import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:jet_rails/jr_app/jr_views/jr_discovery/jr_voice_input_controller.dart';
import 'package:jet_rails/jr_utils/jr_logger.dart';
import 'package:svgaplayer_flutter/player.dart';

class JrVoiceInputWidget extends StatefulWidget {
  const JrVoiceInputWidget({super.key});

  @override
  _JrVoiceInputWidgetState createState() => _JrVoiceInputWidgetState();
}

class _JrVoiceInputWidgetState extends State<JrVoiceInputWidget> {
  final double _maxUpDistance = 15.0;
  double? _startDy;
  Function? _cancel;

  void _onPanUpdate(DragUpdateDetails details) {
    if (_startDy == null) {
      _startDy = details.localPosition.dy;
      setCanSendAudio(true);
    }
    final distance = _startDy! - details.localPosition.dy;
    if (distance > _maxUpDistance) {
      setCanSendAudio(false);
    } else {
      setCanSendAudio(true);
    }
  }

  void _onPanDown(DragDownDetails detail) {
    setCanSendAudio(true);
    Get.find<JrVoiceInputController>().startRecord();
  }

  void _onPanEnd([DragEndDetails? details]) {
    if (Get.find<JrVoiceInputController>().canSendAudio.value) {
      JrLogger.d('IM stopRecord');
      Get.find<JrVoiceInputController>().stopRecord();
    } else {
      JrLogger.d('IM cancelRecord');
      Get.find<JrVoiceInputController>().cancelRecord();
    }
    _startDy = null;
    if (_cancel != null) {
      _cancel!();
      _cancel = null;
    }
    Get.find<JrVoiceInputController>().canSendAudio.value = false;
  }

  void setCanSendAudio(bool canSendAudio) {
    Get.find<JrVoiceInputController>().canSendAudio.value = canSendAudio;
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
        onPanUpdate: _onPanUpdate,
        onPanDown: _onPanDown,
        onPanCancel: _onPanEnd,
        onPanEnd: _onPanEnd,
        child: Container(
          height: 44.h,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(20),
            gradient: const LinearGradient(
                colors: [Color(0xFFCB93DC), Color(0xFFCA67E3)],
                begin: Alignment.centerLeft,
                end: Alignment.centerRight),
            color: const Color(0xFFF1F2F4),
          ),
          alignment: Alignment.center,
          child: const Text(
            'Hold to talk',
            style: TextStyle(color: Colors.white, fontSize: 15),
          ),
        ));
  }
}

class RecordStatusView extends StatefulWidget {
  final Function? cancel;

  const RecordStatusView({super.key, this.cancel});

  @override
  _RecordStatusViewState createState() => _RecordStatusViewState();
}

class _RecordStatusViewState extends State<RecordStatusView> {
  int _second = 0;
  Timer? _timer;

  @override
  void initState() {
    super.initState();

    _timer = Timer.periodic(const Duration(milliseconds: 1000), (t) {
      if (_second == 59) {
        t.cancel();
        widget.cancel?.call();
        _timer = null;
      } else {
        setState(() {
          _second++;
        });
      }
    });
  }

  @override
  void dispose() {
    super.dispose();

    if (_timer?.isActive ?? false) {
      _timer?.cancel();
    }
    _timer = null;
  }

  @override
  Widget build(BuildContext context) {
    return Obx(
      () {
        bool canSendAudio = Get.find<JrVoiceInputController>().canSendAudio.value;
        Widget child = Center(
          child: SizedBox(
            width: 200,
            height: 200,
            child: Column(mainAxisAlignment: MainAxisAlignment.end, children: [
              SizedBox(
                height: 84.h,
                child: canSendAudio
                    ? SizedBox(
                        width: 128.w, child: const SVGASimpleImage(assetsName: 'assets/svg/icon_voice_recording.svga'))
                    : Image(
                        width: 128.w,
                        image: const AssetImage('assets/webp/icon_voice_cancel.webp'),
                        fit: BoxFit.contain,
                      ),
              ),
              Container(height: 56),
              Text(
                canSendAudio ? 'Release Send' : 'Release Cancel',
                style: const TextStyle(
                  fontWeight: FontWeight.w500,
                  fontSize: 15,
                  color: Color.fromRGBO(255, 255, 255, 0.5),
                ),
              ),
            ]),
          ),
        );
        Widget bottomContainer = CustomPaint(
          painter: ArcPainter(),
          child: Container(
            alignment: Alignment.center,
            height: 158.h,
            child: Image.asset(
              !canSendAudio ? 'assets/webp/icon_record_btn_cancel.webp' : 'assets/webp/icon_record_btn_start.webp',
              width: 62.w,
              height: 62.h,
            ),
          ),
        );
        return Container(
          color: const Color(0x99000000),
          child: DefaultTextStyle(
            style: const TextStyle(inherit: false),
            child: Stack(children: [
              child,
              Positioned(
                bottom: 0,
                left: 0,
                right: 0,
                child: bottomContainer,
              ),
              Positioned(
                  bottom: 10,
                  left: 0,
                  right: 0,
                  child: Container(
                      alignment: Alignment.center,
                      child: const Text(
                        'hold and talk',
                        style: TextStyle(color: Colors.black),
                      ))),
            ]),
          ),
        );
      },
    );
  }
}

class ArcPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.fill;

    final path = Path()
      ..moveTo(0, size.height)
      ..lineTo(0, size.height - 128.h)
      ..quadraticBezierTo(
          size.width / 2, size.height - 158.h, size.width, size.height - 128.h)
      ..lineTo(size.width, size.height)
      ..close();

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}
